C
C  This file is part of MUMPS 5.6.2, released
C  on Wed Oct 11 09:36:25 UTC 2023
C
C
C  Copyright 1991-2023 CERFACS, CNRS, ENS Lyon, INP Toulouse, Inria,
C  Mumps Technologies, University of Bordeaux.
C
C  This version of MUMPS is provided to you free of charge. It is
C  released under the CeCILL-C license 
C  (see doc/CeCILL-C_V1-en.txt, doc/CeCILL-C_V1-fr.txt, and
C  https://cecill.info/licences/Licence_CeCILL-C_V1-en.html)
C
      SUBROUTINE ZMUMPS_PROCESS_NODE( MYID,KEEP,KEEP8,DKEEP,
     &           BUFR, LBUFR, LBUFR_BYTES,
     &           IWPOS, IWPOSCB, IPTRLU, LRLU, LRLUS,
     &           N, IW, LIW, A, LA, SLAVEF, PROCNODE_STEPS, DAD,
     &           PTRIST, PTRAST, STEP, PIMASTER, PAMASTER,
     &           NSTK_S, COMP,
     &           FPERE, FLAG, IFLAG, IERROR, COMM,
     &           ITLOC, RHS_MUMPS )
      USE ZMUMPS_DYNAMIC_MEMORY_M, ONLY : ZMUMPS_DM_SET_PTR
      IMPLICIT NONE
      INCLUDE 'mpif.h'
      INTEGER IERR
      INTEGER MYID
      INTEGER LBUFR, LBUFR_BYTES
      INTEGER KEEP(500), BUFR( LBUFR )
      INTEGER(8) KEEP8(150)
      DOUBLE PRECISION DKEEP(230)
      INTEGER(8) :: LA, IPTRLU, LRLU, LRLUS
      INTEGER IWPOS, IWPOSCB
      INTEGER N, LIW
      INTEGER IW( LIW )
      COMPLEX(kind=8) A( LA )
      INTEGER, INTENT(IN) :: SLAVEF
      INTEGER, INTENT(IN) :: PROCNODE_STEPS(KEEP(28)), DAD(KEEP(28))
      INTEGER(8) :: PTRAST  (KEEP(28))
      INTEGER(8) :: PAMASTER(KEEP(28))
      INTEGER PTRIST( KEEP(28) )
      INTEGER STEP(N), PIMASTER(KEEP(28))
      INTEGER COMP, FPERE
      LOGICAL FLAG
      INTEGER NSTK_S( KEEP(28) ), ITLOC( N + KEEP(253) )
      COMPLEX(kind=8) :: RHS_MUMPS(KEEP(255))
      INTEGER IFLAG, IERROR, COMM
      INTEGER POSITION, FINODE, FLCONT, LREQ
      INTEGER(8) :: LREQCB
      INTEGER(8) :: IPOS_NODE, ISHIFT_PACKET
      INTEGER SIZE_PACKET
      INTEGER NBROWS_ALREADY_SENT, NBROWS_PACKET
      INCLUDE 'mumps_headers.h'
      LOGICAL PACKED_CB
      COMPLEX(kind=8), POINTER, DIMENSION(:) :: SON_A
      INTEGER(8) :: DYN_SIZE
      FLAG = .FALSE.
      POSITION = 0
      CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &                FINODE, 1, MPI_INTEGER,
     &                COMM, IERR)
      CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &                FPERE, 1, MPI_INTEGER, 
     &                COMM, IERR)
      CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &                FLCONT, 1, MPI_INTEGER,
     &                COMM, IERR)
      CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &                NBROWS_ALREADY_SENT, 1, MPI_INTEGER,
     &                COMM, IERR)
      CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &                NBROWS_PACKET, 1, MPI_INTEGER,
     &                COMM, IERR)
      PACKED_CB = (FLCONT.LT.0) 
      IF (PACKED_CB) THEN
        FLCONT   = -FLCONT
        LREQCB  = (int(FLCONT,8) * int(FLCONT+1,8)) / 2_8
      ELSE
        LREQCB  = int(FLCONT,8) * int(FLCONT,8)
      ENDIF
      IF (NBROWS_ALREADY_SENT == 0) THEN
        LREQ    = 2 * FLCONT + 6 + KEEP(IXSZ)
        CALL ZMUMPS_ALLOC_CB( .FALSE., 0_8, .FALSE.,.FALSE.,
     &  MYID,N, KEEP,KEEP8, DKEEP, IW, LIW, A, LA,
     &  LRLU, IPTRLU,IWPOS,IWPOSCB, SLAVEF, PROCNODE_STEPS, DAD,
     &  PTRIST,PTRAST,STEP, PIMASTER, PAMASTER,
     &  LREQ, LREQCB, FINODE, S_NOTFREE, .TRUE.,
     &  COMP, LRLUS, KEEP8(67), IFLAG, IERROR
     &     )
        IF ( IFLAG .LT. 0 ) RETURN
        PIMASTER(STEP( FINODE )) = IWPOSCB + 1
        PAMASTER(STEP( FINODE )) = IPTRLU  + 1_8
        IF (PACKED_CB)  IW(IWPOSCB + 1 + XXS ) = S_CB1COMP
        CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &        IW(IWPOSCB + 1+KEEP(IXSZ)), LREQ-KEEP(IXSZ),
     &        MPI_INTEGER, COMM, IERR)
      ENDIF
      IF (PACKED_CB) THEN
        ISHIFT_PACKET = int(NBROWS_ALREADY_SENT,8) *
     &                  int(NBROWS_ALREADY_SENT+1,8) / 2_8
        SIZE_PACKET = (NBROWS_PACKET * (NBROWS_PACKET+1))/2 +
     &                 NBROWS_ALREADY_SENT * NBROWS_PACKET
      ELSE
        ISHIFT_PACKET = int(NBROWS_ALREADY_SENT,8) * int(FLCONT,8)
        SIZE_PACKET = NBROWS_PACKET * FLCONT
      ENDIF
      IF (NBROWS_PACKET.NE.0) THEN
        CALL MUMPS_GETI8(DYN_SIZE, IW(PIMASTER(STEP(FINODE))+XXD))
        IF (DYN_SIZE .GT. 0_8) THEN
          CALL ZMUMPS_DM_SET_PTR( PAMASTER(STEP(FINODE)),
     &                            DYN_SIZE, SON_A )
          IPOS_NODE = 1_8
          CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &         SON_A(IPOS_NODE + ISHIFT_PACKET),
     &         SIZE_PACKET, MPI_DOUBLE_COMPLEX, COMM, IERR)
        ELSE
          IPOS_NODE = PAMASTER(STEP(FINODE))
          CALL MPI_UNPACK(BUFR, LBUFR_BYTES, POSITION,
     &         A(IPOS_NODE + ISHIFT_PACKET),
     &         SIZE_PACKET, MPI_DOUBLE_COMPLEX, COMM, IERR)
        ENDIF
      ENDIF
      IF (NBROWS_ALREADY_SENT+NBROWS_PACKET == FLCONT) THEN
        NSTK_S(STEP(FPERE)) = NSTK_S(STEP(FPERE)) - 1
        IF ( NSTK_S(STEP(FPERE)).EQ.0 ) THEN
          FLAG = . TRUE.
        END IF
      ENDIF
      RETURN
      END SUBROUTINE ZMUMPS_PROCESS_NODE
